package cn.gwm.flink.streaming.dwm.charge.support;

import cn.gwm.flink.streaming.config.ChargeConfigEnum;
import cn.gwm.flink.streaming.constant.BaseFields;
import cn.gwm.flink.streaming.dwm.charge.assist.ChargeSteadyFieldUtil;
import cn.gwm.flink.streaming.dwm.charge.assist.gps.GpsMatchFactory;
import cn.gwm.flink.streaming.dwm.charge.bean.ChargeArgs;
import cn.gwm.flink.streaming.dwm.charge.model.ChargeConstant;
import cn.gwm.flink.streaming.dwm.charge.model.ChargeModelEnum;
import cn.gwm.flink.streaming.dwm.charge.model.ChargeTypeEnum;
import cn.gwm.flink.streaming.dwm.charge.model.PoiTypeCodeEnum;
import cn.gwm.flink.streaming.dwm.charge.util.SupplyUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @ClassName ChargeFieldSupport
 * @Description 充电主题需要计算的字段 的支持类
 * @Author LiangGuang
 * @Date 2023/05/11 18:39
 */
public class ChargeFieldSupport {

    /**
     * 地点匹配
     * 1. 经纬度匹配
     * 2. 地点
     *
     * @param summar
     * @param args
     */
    public static void placeMatching(JSONObject summar, ChargeArgs args) throws Exception {
        // 如果到此处 没有查到 aoi和poi，则需要进行 经纬度拼接
        if ((!summar.containsKey("aoiId") || summar.get("aoiId") == null) && (!summar.containsKey("poiId") || summar.get("poiId") == null)) {
            // 经纬度 保留两位小数 拼接
            if (summar.containsKey(BaseFields.LATITUDE) && !BaseFields.defaultVal.equals(summar.getStr(BaseFields.LATITUDE))) {
                BigDecimal longitude = summar.getBigDecimal(BaseFields.LONGITUDE).setScale(3, BigDecimal.ROUND_HALF_UP);
                BigDecimal latitude = summar.getBigDecimal(BaseFields.LATITUDE).setScale(3, BigDecimal.ROUND_HALF_UP);
                String newAOi = longitude.toString() + StrUtil.COMMA + latitude.toString();
                summar.set("aoiId", newAOi);
            }
        }
    }


    public static void summmarAoi(JSONObject summar, String latitude, String longitude) {
        if (!BaseFields.defaultVal.equals(latitude) && !BaseFields.defaultVal.equals(longitude)) {
            // 修改为逆地理编码查询
//            Map<String, String> supplyCode = SupplyUtil.supplyCode(summar.getBigDecimal(BaseFields.LATITUDE), summar.getBigDecimal(BaseFields.LONGITUDE));
            Map<String, String> supplyCode = SupplyUtil.supplyCode(new BigDecimal(latitude), new BigDecimal(longitude));
            if (supplyCode.size() > 0) {
                summar.set("adCode", supplyCode.get("adCode"));
                summar.set("aoiId", supplyCode.get("aoiId"));
                summar.set("aoiType", supplyCode.get("aoiType"));
                summar.set("poiId", supplyCode.get("poiId"));
                summar.set("poiType", supplyCode.get("poiType"));
            }
            // 首次确认 false  二次为 true
            summar.set("gpsAoi", false);
        }
    }


    /**
     * 设置充电类型
     *
     * @param realNowData 当前数据  --> 确定稳态的那条数据即可
     * @param summar      充电汇总数据
     */
    public static void setChargeType(ChargeConstant constant, JSONObject realNowData, JSONObject summar) {

        if (summar.getInt("OBC_ConnectSts_EV") == 1) {
            // 慢充
            if (!BaseFields.defaultVal.equals(realNowData.getStr(constant.getObcChrgGunSts()))) {
                Integer obcChrgGunSts = realNowData.getInt(constant.getObcChrgGunSts());
                if (obcChrgGunSts == 1 || obcChrgGunSts == 2) {
                    setGun(summar);
                } else if (obcChrgGunSts >= 3) {
                    setBigP(summar);
                }
            } else {
                if (!BaseFields.defaultVal.equals(realNowData.getStr(constant.getObcChrgrOutputVolt()))
                        && !BaseFields.defaultVal.equals(realNowData.getStr(constant.getObcChrgrOutputCurr()))) {
                    // 当前功率
                    BigDecimal nowPower = realNowData.getBigDecimal(constant.getObcChrgrOutputVolt()).multiply(realNowData.getBigDecimal(constant.getObcChrgrOutputCurr()));
                    if (Math.abs(nowPower.intValue()) < Double.valueOf(ChargeConfigEnum.SLOWPOWER.getValue()) * 1000) {
                        setGun(summar);
                    } else {
                        setBigP(summar);
                    }
                } else {
                    if (!BaseFields.defaultVal.equals(realNowData.getStr(constant.getBmsBattCurr()))
                            && !BaseFields.defaultVal.equals(realNowData.getStr(constant.getBmsBattVolt()))) {
                        // 当前功率
                        BigDecimal nowPower = realNowData.getBigDecimal(constant.getBmsBattCurr()).multiply(realNowData.getBigDecimal(constant.getBmsBattVolt()));
                        if (Math.abs(nowPower.intValue()) < Double.valueOf(ChargeConfigEnum.SLOWPOWER.getValue()) * 1000) {
                            setGun(summar);
                        } else {
                            setBigP(summar);
                        }
                    }
                }
            }
        } else {
            // 快充
            if (!BaseFields.defaultVal.equals(realNowData.getStr(constant.getEvccEvseOutput()))) {
                // 此处是不是也会信号变化  --> 超级快充不降级处理
                if (!ChargeTypeEnum.CHARGE_TYPE_QUICK_SUPER.getCode().equals(summar.getStr("chargeType"))) {
                    if (realNowData.getDouble(constant.getEvccEvseOutput()) > Double.valueOf(ChargeConfigEnum.FASTPOWER.getValue()) * 1000) {
                        summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_QUICK_SUPER.getCode());
                    } else {
                        summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_QUICK.getCode());
                    }
                }
            } else {
                if (!BaseFields.defaultVal.equals(realNowData.getStr(constant.getEvccEvseOutputC())) &&
                        !BaseFields.defaultVal.equals(realNowData.getStr(constant.getEvccEvseOutputV()))) {
                    if (!ChargeTypeEnum.CHARGE_TYPE_QUICK_SUPER.getCode().equals(summar.getStr("chargeType"))) {
                        BigDecimal nowPower = realNowData.getBigDecimal(constant.getObcChrgrOutputVolt()).multiply(realNowData.getBigDecimal(constant.getObcChrgrOutputCurr()));
                        if (Math.abs(nowPower.intValue()) > Double.valueOf(ChargeConfigEnum.FASTPOWER.getValue()) * 1000) {
                            summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_QUICK_SUPER.getCode());
                        } else {
                            summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_QUICK.getCode());
                        }
                    }
                } else {
                    if (!BaseFields.defaultVal.equals(realNowData.getStr(constant.getBmsBattCurr())) &&
                            !BaseFields.defaultVal.equals(realNowData.getStr(constant.getBmsBattVolt()))) {
                        if (!ChargeTypeEnum.CHARGE_TYPE_QUICK_SUPER.getCode().equals(summar.getStr("chargeType"))) {
                            BigDecimal nowPower = realNowData.getBigDecimal(constant.getBmsBattCurr()).multiply(realNowData.getBigDecimal(constant.getBmsBattVolt()));
                            if (Math.abs(nowPower.intValue()) > Double.valueOf(ChargeConfigEnum.FASTPOWER.getValue()) * 1000) {
                                summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_QUICK_SUPER.getCode());
                            } else {
                                summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_QUICK.getCode());
                            }
                        }
                    }
                }
            }


            // 此处确定是 快充，判断是否 为快充充电站
            if (summar.containsKey("adCode")) {
                if (!String.valueOf(summar.getStr("aoiType")).startsWith("0110")) {
                    // 调用一次 poi  给定充电站
                    Map<String, String> map = SupplyUtil.supplyPoi(summar.getBigDecimal(BaseFields.LATITUDE), summar.getBigDecimal(BaseFields.LONGITUDE),
                            PoiTypeCodeEnum.CHARGING_STATION.getCode());
                    if (map.size() > 0) {
                        summar.set("adCode", map.get("adCode"));
                        summar.set("aoiType", map.get("aoiType"));
                        summar.set("poiId", map.get("poiId"));
                        summar.set("poiType", map.get("poiType"));
                    }
                }
            } else {
                Map<String, String> map = SupplyUtil.supplyPoi(summar.getBigDecimal(BaseFields.LATITUDE), summar.getBigDecimal(BaseFields.LONGITUDE),
                        PoiTypeCodeEnum.CHARGING_STATION.getCode());
                if (map.size() > 0) {
                    summar.set("adCode", map.get("adCode"));
                    summar.set("aoiType", map.get("aoiType"));
                    summar.set("poiId", map.get("poiId"));
                    summar.set("poiType", map.get("poiType"));
                }
            }

        }
        if (ChargeTypeEnum.CHARGE_TYPE_TO_BE_IDENTIFIED.getCode().equals(summar.getStr("chargeType"))) {
            summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_OTHER.getCode());
        }

    }

    /**
     * 普通的充电模式
     *
     * @param constant
     * @param realNowData
     * @param summar
     */
    public static void setChargeModel(ChargeConstant constant, JSONObject realNowData, JSONObject summar) {
        // chargeModel
        if (!summar.containsKey("chargeModel")) {
            if (realNowData.containsKey(constant.getVcuChrgnSts()) && !"2".equals(realNowData.getStr(constant.getVcuChrgnSts()))) {
                summar.set("chargeModel", ChargeModelEnum.CHARGE_NOW.getCode());
            } else if (realNowData.containsKey(constant.getVcuChrgnSts())) {
                summar.set("chargeModel", ChargeModelEnum.CHARGE_APPOINTMENT.getCode());
            }
        }
    }

    public static void setGun(JSONObject summar) {
        if (!summar.containsKey("chargeType")) {
            summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_SLOW_CAR_GUN.getCode());
        } else {
            if (ChargeTypeEnum.CHARGE_TYPE_OTHER.getCode().equals(summar.get("chargeType")) || ChargeTypeEnum.CHARGE_TYPE_TO_BE_IDENTIFIED.getCode().equals(summar.get("chargeType"))) {
                // 其它或待识别
                summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_SLOW_CAR_GUN.getCode());
            }
        }
    }

    /**
     * 慢充大功率
     *
     * @param summar
     */
    public static void setBigP(JSONObject summar) {
        if (summar.containsKey("chargeType")) {
            String chargeType = summar.getStr("chargeType");
            if (chargeType.equals(ChargeTypeEnum.CHARGE_TYPE_SLOW.getCode()) || chargeType.equals(ChargeTypeEnum.CHARGE_TYPE_SLOW_BUSINESS.getCode())) {
                return;
            }
        }
        if (summar.containsKey("adCode")) {
            // 调用过高德接口  判断
            if (StrUtil.isNotBlank(summar.getStr("aoiType"))) {
                if (summar.getStr("aoiType").startsWith("1203")) {
                    summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_SLOW.getCode());
                } else if (summar.getStr("aoiType").startsWith("0111")) {
                    summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_SLOW_BUSINESS.getCode());
                }
            }
        } else {
            // 前面调用了 逆地理编码，所以此处以poi 补充
            Map<String, String> map = SupplyUtil.supplyPoi(summar.getBigDecimal(BaseFields.LATITUDE), summar.getBigDecimal(BaseFields.LONGITUDE),
                    PoiTypeCodeEnum.CHARGING_STATION.getCode() + "|" + PoiTypeCodeEnum.RESIDENTIAL_DISTRICT.getCode());
            if (map.size() > 0) {
                summar.set("adCode", map.get("adCode"));
                summar.set("aoiId", map.get("aoiId"));
                summar.set("aoiType", map.get("aoiType"));
                summar.set("poiId", map.get("poiId"));
                summar.set("poiType", map.get("poiType"));
                if (String.valueOf(map.get("aoiType")).startsWith("1203")) {
                    // 家用交流充电桩
                    summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_SLOW.getCode());
                } else if (String.valueOf(map.get("aoiType")).startsWith("0111")) {
                    summar.set("chargeType", ChargeTypeEnum.CHARGE_TYPE_SLOW_BUSINESS.getCode());
                }
            }
        }
    }


    /**
     * 校验完整性
     *
     * @param summar
     * @param prevData
     * @param dormancyFlag
     * @param args
     * @return
     */
    public static Boolean setComplete(JSONObject summar, JSONObject prevData, Boolean dormancyFlag, ChargeArgs args) {
        JSONObject nowData = args.getRealNowData();
        // 慢充
        if (summar.getInt("OBC_ConnectSts_EV") == 1) {
            ChargeConstant constant = args.getConstant();
            Double nowBmsSoc = nowData.getDouble(constant.getBmsInnerSOC());
            Double preBmsSoc = prevData.getDouble(constant.getBmsInnerSOC());
            if (Math.abs(nowBmsSoc - preBmsSoc) > 0.5d) {
                // 缺失数据
                summar.set("complete", 0);
                dormancyFlag = Boolean.FALSE;
            }
        } else {
            ChargeConstant constant = args.getConstant();
            Double nowBmsSoc = nowData.getDouble(constant.getBmsInnerSOC());
            Double preBmsSoc = prevData.getDouble(constant.getBmsInnerSOC());
            if (Math.abs(nowBmsSoc - preBmsSoc) > 2.5d) {
                // 缺失数据
                summar.set("complete", 0);
                dormancyFlag = Boolean.FALSE;
            }
        }
        return dormancyFlag;
    }

    /**
     * 当前模式
     *
     * @param source
     * @param constant
     * @return
     */
    public static String chargeModel(JSONObject source, ChargeConstant constant) {
        if (source.getInt(constant.getPlugChrgnMode() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX) == 0) {
            return ChargeModelEnum.CHARGE_NOW.getCode();
        } else if (source.getInt(constant.getPlugChrgnMode() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX) == 1) {
            if (source.getInt(constant.getIntellgntChrgnModResp() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX) == 0) {
                return ChargeModelEnum.CHARGE_APPOINTMENT.getCode();
            } else if (source.getInt(constant.getIntellgntChrgnModResp() + ChargeSteadyFieldUtil.FIELD_STEADY_SUFFIX) == 1) {
                return ChargeModelEnum.CHARGE_SMART.getCode();
            }
        }
        return BaseFields.defaultVal;
    }

    public static Integer getIntVal(JSONObject source, String field) {
        if (source.containsKey(field)) {
            String str = source.getStr(field);
            if (StrUtil.isNotBlank(field) && !BaseFields.defaultVal.equals(str)) {
                return Integer.valueOf(str);
            }
        }
        return 0;
    }

}
